﻿\section{Память}

Есть три основных типа памяти:

\begin{itemize}
\item
Глобальная память \ac{AKA} \q{static memory allocation}.
Нет нужды явно выделять, выделение происходит просто при объявлении переменных/массивов 
глобально.
Это глобальные переменные расположенные в сегменте данных или констант.
Доступны глобально (поэтому считаются \glslink{anti-pattern}{анти-паттерном}).
Не удобны для буферов/массивов, потому что должны иметь фиксированный размер.
Переполнения буфера, случающиеся здесь, обычно перезаписывают переменные или буферы
расположенные рядом в памяти.
Пример в этой книге: \myref{scanf_global_variable}.

\item
Стек \ac{AKA} \q{allocate on stack}, \q{выделить память в/на стеке}.
Выделение происходит просто при объявлении переменных/массивов локально в функции.%
Обычно это локальные для функции переменные.
Иногда эти локальные переменные также доступны и для нисходящих функций (\gls{callee}-функциям, если функция-\gls{caller} передает
указатель на переменную в функцию-\gls{callee}).
Выделение и освобождение очень быстрое, достаточно просто сдвига \ac{SP}.

\myindex{\CStandardLibrary!alloca()}
Но также не удобно для буферов/массивов, потому что размер буфера фиксирован,
если только не используется \TT{alloca()} (\myref{alloca}) (или массив с переменной длиной).

Переполнение буфера обычно перезаписывает важные структуры стека: \myref{subsec:bufferoverflow}.

\myindex{\CStandardLibrary!malloc()}
\myindex{\CStandardLibrary!free()}
\item
Куча (\IT{heap}) \ac{AKA} \q{dynamic memory allocation}, \q{выделить память в куче}.
Выделение происходит при помощи вызова \\
\TT{malloc()/free()} или \TT{new/delete} в \Cpp.

Самый удобный метод: размер блока может быть задан во время исполнения.
\myindex{\CStandardLibrary!realloc()}
Изменение размера возможно (при помощи \TT{realloc()}), но может быть медленным.

Это самый медленный метод выделения памяти: аллокатор памяти должен поддерживать и обновлять
все управляющие структуры во время выделения и освобождения.
Переполнение буфера обычно перезаписывает все эти структуры.
Выделения в куче также ведут к проблеме утечек памяти: каждый выделенный блок должен быть
явно освобожден, но кто-то может забыть об этом, или делать это неправильно.
\myindex{\CStandardLibrary!free()}
Еще одна проблема --- это \q{использовать после освобождения} --- использовать блок памяти после
того как \TT{free()} был вызван на нем, это тоже очень опасно.
Пример в этой книге:
\myref{struct_malloc_example}.

\end{itemize}
